《多型与虚拟》序言节录

首先让我节录《多型与虚拟》一书序言:《多型与虚拟》序节录(侯俊杰/松岗/1998/07)一般而言,C++ 是一个难学易用的语言。C++ 的难学,初始在于其重重的布幕,布幕之中编译程序对我们的程序代码做了太多的手脚,使我们惯于循序思考的工程脑袋一无所措。及长,又面临新的思维模式,使我们必须扭转惯常的思考习惯。C++ 的易用则在于其巨大的弹性,能够以多型(polymorphism)、虚拟(virtual)、模板(template)、泛型(generalization)等种种型式,让既有的码去处理未知的、未来的数据型态。当然,易用必须先能用。用不好或不能用的话,「写C++ 程序」最后就成了只是「使用C++ 编译程序」,这是大家常拿来彼此调侃的笑话。在「难学」的背景下,「易用」是使我们依然前仆后继的动力。愈来愈多的大学信息科系把C++ 开在大一课程,这虽然说明C++ 是多么地重要,可也苦了信息新兵们。其实「难学」的最大症结在于,很难得有一本书,能够一针见血地指出多型与虚拟的重要性;在我们粗具语法基础之后,直接把我们导引到最核心最重要的思想,并且在建立这个思想的过程中,提供足够的必要基础。

●困难度之一

「C++ 是个难学易用的语言」,这句话相信很多人心有戚戚。C++ 的学习难度,一在于语言本身太多的「幕」,一在于"00paradigm shift" (思考模式的移转)。

传统循序语言如C, Pascal, Basic, Fortran...,除了模样看起来稍有不同,基本上都是函式call 来call 去,大同小异,很容易掌握。你想做的动作,在code 中都看得一清二楚。你所看不到的,荦荦大者也不过就是编译程序为你的函式加上用以处理堆栈的一小段码(prologue 和epilogue),这一小段码基本上做的是housekeeping 工作,你没看到也没有关系(更好),并不影响你对程序逻辑的思考。

C++ 不一样,C++ 有太多和程序逻辑息息相关的动作是编译程序为我们加上去的。换句话说C++ 编译程序为我们「加码」。如果不识清这一节,学习C++ 有如雾里看花,雾非雾,花非花。

编译程序为我们的C++ 程序加了什么码呢?很多!对象诞生时ctor 会被唤起,物件死亡时dtor 会被唤起,这都是

加码的结果。ctor 中设定vtpr 和vtbl,这也是加码的结果。new 单一对象时会产生memory block cookie,new 对象数组时会产生一个内部结构记录着object size 和class ctor...,这也都是布幕后的工作。可以说,程序代码中看不到而却必须完成的所有与程序逻辑有关的动作,统统都是C++ 编译程序加码后的结果。

当「继承」发生,整个情况变得稍微复杂起来。「多重继承」又更复杂一些,「虚拟继承」再更复杂一些。

这些布幕后的主题,统可归类为所谓的C++ object model(对象模型)。如果不知道这些底层机制,你就只能够把"make destructors virtual in base classes"(, item14)或"never treat arrays polymorphically" (, item 3)这类规则硬背下来,却不明白它的道理。

用一样东西,却不明白它的道理,林语堂如是说:『不高明』。只知道how,不知道why,侯捷如是说:『不高明』。

●困难度之二

C++ 的第二个学习难度在于"paradigm shift"(思考模式的移转)。别说自己设计classes 了,光使用别人的classes,就都是一种思考模式和行为模式的移转。MFC(或OWL 或VCL)programmer 必然甚能够领略并体会我的意思。

使用所谓的application framework(一种大型的、凝聚性强的、有着面向对象公共基础建设的class library),你的码和framework 之间究竟是怎样的关系呢?framework 提供的一大堆可改写的虚拟函式的意义与价值究竟在哪里呢?为什么framework 所设计的种种美好性质以及各式各样的算法竟然可以施行于我们自己设计的class types 身上呢?framework 被设计时,并不知道我们的存在呀!

这正是面向对象中的多型(polymorphism)的威力。

稍早所说的C++ 对象模型,偏属程序设计的低层面;这里所说的思考模式移转,则是程序设计的高层面。能够把新思维模式的威力发挥得最淋漓尽致的,当推面向对象的polymorphism(多型)和generalization(泛型)。如果你没有使用这两项特性,等于入C++ 宝山而空手返。

●反复焠炼,循环震荡

想象C++ 是一把用来解决程序问题的刀,要它坚轫,要它锋利,就必须经过多次的回火,在高热和骤冷之间焠炼。

初学C++ 语法(syntax)之后,你应该尽快尝试体验polymorphism (大致而言也就是虚拟函式的运用)。等到对OOP 的精神有了大局掌控的能力,但对C++ 的许多小细节不甚清楚,就是回到C++ 对象模型焠炼的时机。

成长,是在高阶(polymorphism)和低阶(object model)之间反复震荡,才能够震荡到更高的位阶,而不是平平庸庸于中阶(C++ syntax)的一滩死水。

●不要沉沦于C++ syntax

100 个人跟我说他懂C++/OOP,只有10% 不到可以让我认为他没有胡吹大气。太多的人,上嘛上不到polymorphism,下嘛又下不到object model。就这样不上不下地卡在C++ 语法层面。大一学了C++,到大四快毕业了,连virtual functions 是怎么回事都期期艾艾支支吾吾说不出个道理。

有时候我觉得,太苛责同学也于心不忍,因为同学们事实上处于一种无知的状态,既不知道C++/OOP 该怎么学,也不知道哪些书可以教他们那么学。所以,苛责同学,不如责怪老师。

众所周知,大学教授泰半是动口不动手,普遍的心态是「论文第一,升等为要;程序语言?哎,末流!」。「末流」课程通常由教授们轮流教,谁倒霉谁来教;于是就常常有「下学期要教C++ 语言了,这学期寒(暑)假赶快去要本书来恶补」的情况发生。偏偏程序语言这东西,只动口不管用,一定要动手,而且要常动手。老师自己没有摸到C++/OOP 的精神,学生又能学到什么?

有些学校信息系并不教特定的程序语言,老师们的态度是「语言是一种自己学就好了的东西嘛,拿到大学殿堂来,哎,不入流」!于是应该好好为学生打下实际基础的课程,却天马行空地腾云驾雾起来,大谈抽象意念。饱读经书的老师们可能忽略了,一个完全没有技术基础的学子,要的不是形而上的道,而是形而下的器。

我们是先能够欣赏具象画,还是先能够欣赏抽象画?我们不都是先对毕加索的画大骂「这是什么东西」,直到自己的艺术涵养够丰富了、人生阅练更饱满了、能够举一隅以三隅反了、能够接触类旁通左右逢源了,才转而能够欣赏甚至进入毕加索的抽象意境吗?

老师们各有专长,要老师们来教非彼专长的大班课、基础课,我又觉得似乎也太为难老师了。那么,苛责老师,不如责怪学校当局。如果学校当局能够聘请经验老道又有教学热诚的工程师来教这类实务学科,不是三方皆大欢喜吗?不要说什么制度僵化啦,难以突破啦,大学是高度自治区,礼聘几位兼任老师,不全都是系上的权责范围内吗?

当学子们在课程上学不到他要的东西,就只好闭门自修。但是,循序性(sequential)语言尚有自修学会的可能,面向对象语言嘛,以大学生的程度来讲,我认为自修实在困难,只会修出个四不像、半瓶水。

管不到学校!管不到教授!自求多福的情况下,希望看到这篇文章的你,知道C++/OOP 该怎么学。

●不要沉迷于C++ object model

对于底层知识有浓厚兴趣的朋友,下探到object model 领域,一定会非常开心地在object size、object layout、vptr/vtbl、以及许多布幕后的技术之间玩将起来。了解这些东西,当然是好的,但是由于一探究竟得其奥秘的快感与成就感,使得一些朋友们在这个层面里「玩」起来了,小地方玩得很精,玩得不亦乐乎,玩得忽略了C++/OOP 的最终目标。

最终目标是polymorphism!

我要说,在C++ syntax 以及相对低阶的C++ semantics 里,不要玩得太过火。过犹不及,会伤身的。C++ 经典名书内附的一些习题,在我看来颇有点玩得过火的味道。至于什么百题精选、题库大成,除了修练基本功之外,都满无趣的东西。

Programming 应该是一种天马行空的想象力与创意的组合;如果你能够自己想题目,譬如说实作一个天体运行的class 体系、或是实作一个生物分类(界门纲目科属种)体系,不是很有趣吗?准备数据的过程中,查查百科全书,你也因此查到了太阳系九大行星的几何数据,哈雷慧星的轨道周期,或是黑面琵鹭的「界门纲目科属种」英文名称,这难道不比钻研于++++i 或----i 或*&*&p 之类的头脑体操题目有趣吗?(看过不少这类好笑题目,没一个记下来,如果没有介绍几本好书,我就是为德不卒。

让我再节录《多型与虚拟》的二刷感言:

... C++ 相关书籍,如天上繁星,如过江之鲫。广博如四库全书者有之(如The C++ Programming Language、C++ Primer),深奥宛如山重水复有之(如Inside The C++ Object Model),独沽一味者有之(如C++ Programming Style、More Effective C++),独树一帜者有之(如The Design and Evolution of C++),另辟蹊径者亦有之(如STL tutorial Reference Guide)。...

以下是我认为你应该要拥有的书籍。有趣的是,我才在自己班上做了一个调查(我教的是面向对象Windows 程序设计,学生应该要有良好的C++/OO 基础),拥有以下1~5 本书的人举手。举手人数都很少,而且老是那几位(最高记录是拥有四本)。这让我感觉,强者恒强,弱者恒弱。悲夫!

1. C++ Primer (3/e), Lippman/A.W./1998

听说1999 将有中译

2. 2. The C++ Programming Language (3/e), Bjarne/A.W./1997

听说1999 将有中译本

以上两本书是C++ 经典百科。就内容水平而言,我认为同为瑜亮。普遍的印象是,第一本较易接受,第二本涩味稍重。第二本书作者Bjarne 是C++ 语言的创造者,所以有其权威性。我认识的多位C++/OOP 高手,都是两书齐具。

3. Inside The C++ Object Model, Lippman/A.W./199651

观点

中译本《深度探索C++ 对象模型》

此书全册讲解C++ object model,上穷碧落下黄泉。内容很好,层次也高,可惜原文书大大小小的错误繁如晨星,阅读时需小心。

4. Effective C++, Meyers/A.W./1992

印象似有中译本,名称忘了,谁可补充说明?

5.More Effective C++, Meyers/A.W./1996

有中译本吗?我不知道,谁可补充说明?

以上是同一作者的两本书,专讲C++ programming 的重要观念,使你的程序更稳健更有效率。书中许多观念涉及C++ object model,与(3) 混合看将如鱼得水。

6. Polymorphism in C++ <多型与虚拟> 侯俊杰/松岗/1998

没有中译本--它本身就是中文书

在语法粗具的基础上,直接把读者导引到最核心最重要的思想,并且在建立这个思想的过程中,提供足够的必要基

础。

我只列出一本中文书,是因为这方面的中文书我看得少,英文书看得多。「恐有遗珠之憾」这类「八方得体」的话,还是说一下好了:)。

注意,这些都只是强本固元用来扎基础的书籍而已,要观摩大型程序经验,还有诸如Large Scale C++ Software Design(John Lakos/A.W./1996)可以阅读。

OO 的世界,不止OOP,还有OOA/OOD,那又是一缸子的学问和一缸子的书。

---end

本页共59段,5543个字符,12636 Byte(字节)